package com.qf.controller;

import com.qf.captcha.CaptchaCodeManager;
import com.qf.pojo.DtsAdmin;
import com.qf.service.DtsPermissionService;
import com.qf.service.DtsRoleService;
import com.qf.util.Base64;
import com.qf.util.ResponseUtil;
import com.qf.util.UUID;
import com.qf.util.VerifyCodeUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.annotation.Around;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author YDW
 * projectName:shop-manage
 * time:2022/5/17 16:30
 * description:
 */


@RestController
@RequestMapping("/admin/auth")
public class AdminAuthController {
    @Autowired
    DtsRoleService roleService;

    @Autowired
    DtsPermissionService permissionService;

    @RequestMapping("/logout")
    public Object logout(){
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.logout();
        return ResponseUtil.ok();
    }


    @GetMapping("/info")
    public Object info(){
        Subject subject = SecurityUtils.getSubject();
        //获取DtsAdmin对象
        DtsAdmin admin= (DtsAdmin) subject.getPrincipal();
        System.out.println(admin);
        Map<String ,Object> data=new HashMap<>();

        //需要查询角色
        Set<String> roles = roleService.findRoleByIds(admin.getRoleIds());
        data.put("roles",roles);

        data.put("name",admin.getUsername());

        //需要查询权限
        Set<String> perms = permissionService.findPermByIds(admin.getRoleIds());
        data.put("perms",perms);

        data.put("avatar",admin.getAvatar());
        return ResponseUtil.ok(data);

    }


    @RequestMapping("/login")
    public Object login(@RequestBody Map<String,String> map, HttpSession session){
        //获取请求参数
        String code =map.get("code");//从前端用户输入的
        String password =map.get("password");
        String username =map.get("username");
        String uuid =map.get("uuid");

        //校验验证码
        //从服务器（缓存） 获取生成的验证码
        String cachedCaptcha=CaptchaCodeManager.getCachedCaptcha(uuid);
        if(code==null){
            return ResponseUtil.fail(-1,"验证码已过期");
        }
        if(!code.equalsIgnoreCase(cachedCaptcha)){
            return ResponseUtil.fail(-1,"验证码输入有误");
        }

        //（shiro）登录操作
        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token=new UsernamePasswordToken(username,password);

        //subject.login(token);登录方法
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            System.out.println(e.getMessage());
            return ResponseUtil.fail(-1,"用户不存在");
        } catch (LockedAccountException e) {
            System.out.println(e.getMessage());
            return ResponseUtil.fail(-1,"该账户已锁定");
        } catch (CredentialsException e) {
            System.out.println(e.getMessage());
            return ResponseUtil.fail(-1,"密码输入有误");
        }
        return ResponseUtil.ok(session.getId());

    }



    @GetMapping("/captchaImage")
    public Object captchaImage() throws IOException {
        //生产验证码
        //生产指定位数的验证码
        String code= VerifyCodeUtils.generateVerifyCode(2);
        //创建输出流对象
        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
        //生产验证码图片
        VerifyCodeUtils.outputImage(120,40,outputStream,code);
        //把输出流的内容转换为字节数组，方便传输，为了安全，要对验证码图片数据进行加密
        //唯一标识
        String uuid= UUID.randomUUID().toString().replaceAll("-","");

        //把验证码存储到缓存中
        CaptchaCodeManager.addToCache(uuid,code,5);

        Map<String,Object> data=new HashMap<>();
        data.put("img", Base64.encode(outputStream.toByteArray()));
        data.put("uuid",uuid);

        //此处对应了前端需要的数据结构
        return ResponseUtil.ok(data);
    }


}
